(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  typeof define === 'function' && define.amd ? define([], factory) :
  global.graphUtil = factory();
}(this, function () { 'use strict';

  /**
   * hex: string
   * rgb: string
   * color: array
   */

  function splitHex(hex) {
    if (Array.isArray(hex)) { // to avoid sth error
      hex = hex[0]
    }
    if (!hex) {
      return hex
    }
    if (hex.substr(0, 1) !== '#') {
      hex = '#' + hex
    }
    hex = hex.replace('#', '0x')
    if (hex.length !== 8) {
      //颜色值只有三位的情况
      let str1 = hex.substr(2, 1)
      let str2 = hex.substr(3, 1)
      let str3 = hex.substr(4, 1)
      hex = '0x' + str1.repeat(2) + str2.repeat(2) + str3.repeat(2)
    }
    let r = hex >> 16
    let g = hex >> 8 & 0xFF
    let b = hex & 0xFF
    return [r, g, b];
  }


  function splitRgb(rgb) {
    if (!rgb) {
      return
    }

    var argb = rgb.match(
      /^rgba?[\s]*\([\s]*(\d+)[\s]*,[\s]*(\d+)[\s]*,[\s]*(\d+)[\s]*,?[\s]*(\d*\.?\d*)[\s]*\)$/i
    )

    if (argb) {
      var color = [
        parseInt(argb[1] || 0, 10),
        parseInt(argb[2] || 0, 10),
        parseInt(argb[3] || 0, 10)
      ]

      if (argb[4]) {
        color.push(argb[4]);
      }
      return color;
    }
  }

  function joinHex(color) {
    var hex = '#' +
      ('0' + parseInt(color[0], 10).toString(16)).slice(-2) +
      ('0' + parseInt(color[1], 10).toString(16)).slice(-2) +
      ('0' + parseInt(color[2], 10).toString(16)).slice(-2)
    
    return hex;
  }

  function joinRgb(color, opacity) {
    opacity = opacity != undefined ? opacity : color[3];
    if (opacity != undefined) {
      return ['rgba(', color[0], ',', color[1], ',', color[2], ', ', opacity, ')'].join('');
    } else {
      return ['rgb(', color[0], ',', color[1], ',', color[2], ')'].join('');
    }
  }

  function isHex(str) {
    return /^#[\d|a-z|A-Z]{6}$/.test(str) || /^#[\d|a-z|A-Z]{3}$/.test(str)
  }

  function parse2Color(colorStr) {
    if (isHex(colorStr)) {
      return splitHex(colorStr)
    } else {
      return splitRgb(colorStr)
    }
  }

  /**
   * https://www.zhangxinxu.com/wordpress/2010/03/javascript-hex-rgb-hsl-color-convert/
   * HSL颜色值转换为RGB. 
   * 换算公式改编自 http://en.wikipedia.org/wiki/HSL_color_space.
   * h, s, 和 l 设定在 [0, 1] 之间
   * 返回的 r, g, 和 b 在 [0, 255]之间
   *
   * @param   Number  h       色相
   * @param   Number  s       饱和度
   * @param   Number  l       亮度
   * @return  Array           RGB色值数值
   */
  function hslToRgb(h, s, l) {
    var r, g, b;

    if(s == 0) {
      r = g = b = l; // achromatic
    } else {
      var hue2rgb = function hue2rgb(p, q, t) {
        if (t < 0) t += 1;
        if (t > 1) t -= 1;
        if (t < 1/6) return p + (q - p) * 6 * t;
        if (t < 1/2) return q;
        if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
        return p;
      }

      var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
      var p = 2 * l - q;
      r = hue2rgb(p, q, h + 1/3);
      g = hue2rgb(p, q, h);
      b = hue2rgb(p, q, h - 1/3);
    }

    return [Math.round(r*255), Math.round(g*255), Math.round(b*255)];
  }

  /**
   * https://www.zhangxinxu.com/wordpress/2010/03/javascript-hex-rgb-hsl-color-convert/
   * RGB 颜色值转换为 HSL.
   * 转换公式参考自 http://en.wikipedia.org/wiki/HSL_color_space.
   * r, g, 和 b 需要在 [0, 255] 范围内
   * 返回的 h, s, 和 l 在 [0, 1] 之间
   *
   * @param   Number  r       红色色值
   * @param   Number  g       绿色色值
   * @param   Number  b       蓝色色值
   * @return  Array           HSL各值数组
   */
  function rgbToHsl(r, g, b) {
    r /= 255, g /= 255, b /= 255;
    var max = Math.max(r, g, b), min = Math.min(r, g, b);
    var h, s, l = (max + min) / 2;

    if (max == min) { 
      h = s = 0; // achromatic
    } else {
      var d = max - min;
      s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
      switch (max) {
        case r: h = (g - b) / d + (g < b ? 6 : 0); break;
        case g: h = (b - r) / d + 2; break;
        case b: h = (r - g) / d + 4; break;
      }
      h /= 6;
    }

    return [Math.round(h*360), Math.round(s*1000)/10, Math.round(l*1000)/10];
  }

  return {
    splitHex: splitHex,
    splitRgb: splitRgb,
    joinHex: joinHex,
    joinRgb: joinRgb,
    parse2Color: parse2Color,
    hsl2Rgb: hslToRgb,
    rgb2Hsl: rgbToHsl
  }

}))
